/**
 * Tencent is pleased to support the open source community by making QMUI Web Desktop available.
 * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://opensource.org/licenses/MIT
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language governing permissions and
 * limitations under the License.
 */

"use strict";

const path = require("path");
const fs = require("fs-extra");
const childProcess = require("child_process");
const _ = require("lodash");
const ipcRenderer = require("electron").ipcRenderer;
const Common = require(path.join(__dirname, "./src/common"));
const Core = require(path.join(__dirname, "./src/core"));
const remote = require("electron").remote
const mainProcess = remote.process;

// 变量声明
let $wrapper = $("#wrapper");
let $welcomeStage = $("#welcomeStage");
let $openProject = $("#openProject");
let $projectStage = $("#projectStage");
let $projectList = $("#projectList");
let $installButton = $("#installButton");
let $gulpButton = $("#gulpButton");
let $mergeButton = $("#mergeButton");
let $cleanButton = $("#cleanButton");
let $delProject = $("#delProject");
let $operationStage = $("#operationStage");
let $logContent = $("#log");
let $cleanLog = $("#cleanLog");
let $closeSettingButton = $("#closeSetting");
let $showSettingButton = $("#showSetting");
let $settingStage = $("#settingStage");
let $settingStageMask = $("#settingStageMask");
let $toolbar = $("#toolbar");
let $curProject = { connectStatus: 0 };
let finderTitle = Common.PLATFORM === "win32" ? "打开项目文件夹" : "打开项目目录";
let closeGulpManually = false;
let justInitStatusBar = true;
let $serverModal = $("#serverModal");

ipcRenderer.on("message", function(event) {
  event.send("dd");
});
ipcRenderer.on('log', function(arg) {
  logReply(logTextWithDate(arg))
})
ipcRenderer.on("open-file-dialog",(e)=>{

})
// 输出平台相关的标识 class
if (Common.PLATFORM === "win32") {
  $wrapper.addClass("qw_windows");
} else {
  $wrapper.addClass("qw_macOS");
}

// 状态栏
if (Common.PLATFORM === "win32") {
  // Windows 下处理，需要调换最小化按钮和最大化按钮的位置，配合 Windows 上的习惯
  togglePostion($(".js_statusBar_min"), $(".js_statusBar_max"));
} else {
  // Mac 下处理，hover 时所有状态栏按钮显示 icon
  $("#statusBar_inner").hover(
    function() {
      $(".frame_statusBar_btn").addClass("frame_statusBar_btn_Hover");
    },
    function() {
      $(".frame_statusBar_btn").removeClass("frame_statusBar_btn_Hover");
    }
  );
}
//初始化 popover
$('[data-toggle="popover"]').popover();

$(".js_statusBar_min").on("click", function() {
  remote.BrowserWindow.getFocusedWindow().minimize();
});

$(".js_statusBar_max").on("click", function() {
  const focusedWindow = remote.BrowserWindow.getFocusedWindow();
  // 因为每次打开 App 时，isMaximizable 都会为 true，但实际上窗口并没有最大化，因此加入一个标志位判断是否刚刚打开 App
  if (focusedWindow.isMaximizable() && !justInitStatusBar) {
    focusedWindow.unmaximize();
    focusedWindow.setMaximizable(false);
    $(this).removeClass("frame_statusBar_btn_Unmax");
  } else {
    justInitStatusBar = false;
    focusedWindow.maximize();
    focusedWindow.setMaximizable(true);
    $(this).addClass("frame_statusBar_btn_Unmax");
  }
});

$(".js_statusBar_close").on("click", function() {
  remote.BrowserWindow.getFocusedWindow().close();
});

$("#addServer").on("click", function() {
  let storage = Common.getLocalStorage(),
    item = {};
  if(isEdit){
    item = storage["projects"][EditIndex]
    $serverModal.find("input").each(function(i, el) {
      item[el.name] = el.value;
    });
  }else{
    $serverModal.find("input").each(function(i, el) {
      item[el.name] = el.value;
    });
    if (_.isEmpty(storage["projects"])) {
      storage["projects"] = [];
    }
    storage["projects"].push(item);
  }

  Common.setLocalStorage(storage);
  $serverModal.modal("hide");
  initData();
});

// 禁止缩放
//electron.webFrame.setZoomLevelLimits(1, 1);

// 初始化
init();

// 如果是第一次打开,设置数据并存储
// 其他则直接初始化数据
function init() {
  let storage = Common.getLocalStorage();

  if (!storage) {
    storage = {};
    storage.name = Common.NAME;
    storage["setting"] = {};
    storage["setting"]["compass"] = {};
    storage["setting"]["compass"]["notification"] = "true";
    storage["setting"]["compass"]["statusIcon"] = "true";

    let workspace = path.join(
      remote.app.getPath(Common.DEFAULT_PATH),
      Common.WORKSPACE
    );

    storage.workspace = workspace;
    Common.setLocalStorage(storage);
  } else {
    $projectStage.removeClass("qw_hide");
    $operationStage.removeClass("qw_hide");
    $welcomeStage.addClass("qw_hide");
    $toolbar.removeClass("frame_toolbar_EmptyProject");
    initData();
  }
}

// 初始化数据
function initData() {
  let storage = Common.getLocalStorage();

  if (storage) {
    if (!_.isEmpty(storage["projects"])) {
      let html = "";
      //<a class="qw_icon qw_icon_Connect js_Connect" data-toggle="popover" href="javascript:;" title="未连接"></a>
      for (let i in storage["projects"]) {
        html += `<li class="project_stage_item js_project_item"
                  data-project="${i}"
                  data-name="${storage["projects"][i]["nickName"]}"
                  title="${storage["projects"][i]["host"]}">
                          <a class="qw_icon qw_icon_Edit js_edit" href="javascript:;" title="编辑"></a>
                          <div class="project_stage_item_cnt">
                            <div class="project_stage_item_title">${storage["projects"][i]["nickName"]}</div>
                            <div class="project_stage_item_path">${storage["projects"][i]["host"]}</div>
                          </div>
                        </li>`;
      }

      $projectList.html(html);

      // 当前活动项目
      $curProject = $projectList.find(".js_project_item").eq(0);
      $curProject.addClass("project_stage_item_Current");

      let projectPath = $curProject.attr("title");
      let qmuiModulePath = projectPath + "/UI_dev/qmui_web/node_modules";
      if (!fs.existsSync(qmuiModulePath)) {
        $gulpButton.addClass("qw_hide");
        $mergeButton.addClass("qw_hide");
        $cleanButton.addClass("qw_hide");
        $installButton.removeClass("qw_hide");
      } else {
        $gulpButton.removeClass("qw_hide");
        $mergeButton.removeClass("qw_hide");
        $cleanButton.removeClass("qw_hide");
        $installButton.addClass("qw_hide");
      }

      // 复制一份数据到 sessionStorage，方便后续使用
      Common.setSessionStorage(storage);
    } else {
      $welcomeStage.removeClass("qw_hide");
      $projectStage.addClass("qw_hide");
      $operationStage.addClass("qw_hide");
      $toolbar.addClass("frame_toolbar_EmptyProject");
    }
  }
}


// 删除项目
$delProject.on("click", function() {
  let projectIndex = $curProject.data("project");
  let projectName = $curProject.data("name");
  delProject(function() {
    $("#delServerModal").modal("hide");
    new $.zui.Messager(`已删除 ${projectName} `, {
      type: "success" // 定义颜色主题
    }).show();
  });
});

function delProject(cb) {
  if (!$curProject.length) {
    return;
  }

  let projectIndex = $curProject.data("project");
  let index = $curProject.index();
  $curProject.remove();

  if (index > 0) {
    $curProject = $(".project_stage_item").eq(index - 1);
  } else {
    $curProject = $(".project_stage_item").eq(index);
  }

  //$curProject.trigger("click");
  let storage = Common.getLocalStorage();
  if (storage && storage["projects"] && storage["projects"][projectIndex]) {
    storage["projects"].splice(projectIndex, 1)
    console.log(storage["projects"])
    Common.setLocalStorage(storage);
  }

  if (_.isEmpty(storage["projects"])) {
    $welcomeStage.removeClass("qw_hide");
    $projectStage.addClass("qw_hide");
    $operationStage.addClass("qw_hide");
    $toolbar.addClass("frame_toolbar_EmptyProject");
  }

  console.log("Delete project success.");
  cb && cb();
}

// 清除 log 信息
$cleanLog.on("click", function() {
  // 清空 Log 界面
  $logContent.html("");
  // 清空 Storage
  let projectDir = $curProject.data("project");
  let sessionStorage = Common.getSessionStorage();
  sessionStorage["projects"][projectDir]["log"] = "";
  Common.setSessionStorage(sessionStorage);
});

// 项目列表绑定点击事件
$projectList.on("click", ".js_project_item", function() {
  let $this = $(this);
  let storage = Common.getLocalStorage();
  let sessionStorage = Common.getSessionStorage();
  if ($this.index() != $curProject.index()) {
    $(".js_project_item").removeClass("project_stage_item_Current");
    $this.addClass("project_stage_item_Current");
    $curProject = $this;
  } else {
    storage["projectIndex"] = $this.index();
    Common.setLocalStorage(storage);
    showServerDetail($curProject.data("name"));
  }
});

//编辑
let isEdit = false
let EditIndex
$projectList.on('click','.js_edit', function (e) {
  e.stopPropagation()
  isEdit = true
  let storage = Common.getLocalStorage();
  let $this = $(this);
  let editIndex = $this.parents('.js_project_item').data('project');
  EditIndex = editIndex
  let item = storage["projects"][editIndex];
  $serverModal.find("input").each(function(i, el) {
    el.value = item[el.name] ? item[el.name] : ''
    if(el.name=="docker"){
      el.checked = el.value=="true"
      el.checked ? $('#dockerMode').show() : $('#dockerMode').hide()
    }
  });
  $('#addServer').text("更新")
  $serverModal.modal("show")
})
//添加对话框关闭后重置操作
$serverModal.on('hide.zui.modal',function () {
  isEdit = false
  $('#dockerMode').hide()
  $('#addServer').text("添加")
  $serverModal.find("input").each(function(i, el) {
    el.value='';
    el.checked ? el.checked=false:''
  });
})

// 结束子进程
function killChildProcess(projectDir) {
  let storage = Common.getLocalStorage();

  if (
    storage &&
    storage["projects"][projectDir] &&
    storage["projects"][projectDir]["pid"]
  ) {
    try {
      if (Common.PLATFORM === "win32") {
        childProcess.exec(
          "taskkill /pid " + storage["projects"][projectDir]["pid"] + " /T /F"
        );
      } else {
        process.kill(storage["projects"][projectDir]["pid"]);
      }
    } catch (e) {
      console.log("pid not found");
    }

    storage["projects"][projectDir]["pid"] = 0;
    Common.setLocalStorage(storage);

    $('.js_project_item[data-project="' + projectDir + '"]').removeData("pid");
  }
}

function logReply(data, projectIndex) {
  let originData = data;
  let curProjectPath = $curProject.attr("title");
  let sessionStorage = Common.getSessionStorage();
  data = data.replace(/\n/g, "<br/>");
  data = data.replace(
    /\[(.*?)\]/g,
    '[<span class="operation_stage_log_time">$1</span>]'
  ); // 时间高亮
  data = data.replace(
    /\'(.*?)\'/g,
    "'<span class=\"operation_stage_log_keyword\">$1</span>'"
  ); // 单引号内的关键词高亮
  data = data.replace(
    /(QMUI .*?):/,
    "'<span class=\"operation_stage_log_qmui\">$1</span>'"
  ); // QMUI 任务名高亮
  if (projectIndex === projectIndex) {
    $logContent.append(`${data}`);
    $logContent.scrollTop($logContent.get(0).scrollHeight);
  }

  // 把 log 写入 sessionStorage
  sessionStorage["projects"][projectIndex]["log"] += data;
  Common.setSessionStorage(sessionStorage);

  // 样式编译完成后发通知
  let localStorage = Common.getLocalStorage();
}
function docker(el) {
  el.value = el.checked
  el.checked ? $('#dockerMode').show() : $('#dockerMode').hide()
}

// 设置界面
$showSettingButton.on("click", function() {
  $settingStageMask.removeClass("qw_hide");
  $settingStage.removeClass("qw_hide");
});
$settingStageMask.on("click", function() {
  $settingStageMask.addClass("qw_hide");
  $settingStage.addClass("qw_hide");
});

$settingStage.on("change", "input", function() {
  let $this = $(this);
  let name = $this.attr("id");
  // let val = $.trim($this.val());
  let checked = $this.prop("checked");
  let type = $this.attr("type");
  let storage = Common.getLocalStorage();

  let nameArr = name.split("_");
  let pname = nameArr[0];
  let cname = nameArr[1];

  if (type === "checkbox") {
    storage["setting"][pname][cname] = checked.toString();
    Common.setLocalStorage(storage);
  }
});


//打开服务器详情页
function showServerDetail(title) {
  const BrowserWindow = remote.BrowserWindow;
  let win = new BrowserWindow({
    width: 360,
    height: 640,
    resizable: true,
    title: title,
    frame: false
  });

  // win.webContents.openDevTools();
  let detailPath = "file://" + __dirname + "/detail.html";
  win.loadURL(detailPath);
  win.on("closed", function() {
    win = null;
  });
  const windowID = BrowserWindow.getFocusedWindow().id;
  console.log('appWindowId',windowID)
  win.webContents.on("did-finish-load", function() {
    win.webContents.send("init", windowID);
  });
}

// 调试

// 重置储存数据
function resetAppStorage() {
  $.prompt("重置储存数据会清空本 App 中所有的相关数据，包括项目数据。", {
    title: "确认重置储存数据",
    buttons: { 确认: true, 取消: false },
    submit: function(e, v, m, f) {
      if (v) {
        Common.resetLocalStorage();
        Common.resetSessionStorage();
        remote.getCurrentWindow().reload();
      }
    }
  });
}

// 工具方法

// 时间格式
function dateFormat(date) {
  if (date.toString().length == 1) {
    return "0" + date;
  }
  return date;
}

// 生成带时间的 Log
function logTextWithDate(content) {
  let D = new Date();
  let h = dateFormat(D.getHours());
  let m = dateFormat(D.getMinutes());
  let s = dateFormat(D.getSeconds());
  return `[${h}:${m}:${s}] ${content}<br/>`;
}

// 交换两个 DOM 顺序
function togglePostion(a, b) {
  var temp1 = $('<div id="a1"></div>').insertBefore(a),
    temp2 = $('<div id="b1"></div>').insertBefore(b);

  a.insertAfter(temp2);
  b.insertAfter(temp1);
  temp1.remove();
  temp2.remove();
  temp1 = temp2 = null;
}

// 比较两个版本号的大小
// Return 1 if a > b
// Return -1 if a < b
// Return 0 if a == b
function compareVersion(a, b) {
  if (a === b) {
    return 0;
  }

  var aComponents = a.split(".");
  var bComponents = b.split(".");

  var len = Math.min(aComponents.length, bComponents.length);

  // loop while the components are equal
  for (var i = 0; i < len; i += 1) {
    // A bigger than B
    if (parseInt(aComponents[i], 10) > parseInt(bComponents[i], 10)) {
      return 1;
    }

    // B bigger than A
    if (parseInt(aComponents[i], 10) < parseInt(bComponents[i], 10)) {
      return -1;
    }
  }

  // If one's a prefix of the other, the longer one is greater.
  if (aComponents.length > bComponents.length) {
    return 1;
  }

  if (aComponents.length < bComponents.length) {
    return -1;
  }

  // Otherwise they are the same.
  return 0;
}
